/**
 * Copyright(c) 2013 Jade Techonologies Co., Ltd.
 *
 * History:
 *   13-7-5 下午3:46 Created by dwzhang
 */
package com.jade.framework.base.io;

import java.io.File;
import java.io.FileFilter;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import com.jade.framework.base.JadeSystem;
import org.apache.commons.lang3.StringUtils;

/**
 * 临时文件存储。
 *
 * @author dwzhang
 * @version 1.0 13-7-5 下午3:46
 */
public class TempFileStore extends SimpleFileStore implements Runnable
{
    protected static final String TEMP_HOME = "temp.home";
    protected static final int KEEP_TIME = 3 * 3600 * 1000;
    private int keepTime = KEEP_TIME;
    private ScheduledExecutorService executorService;

    @PostConstruct
    public void start()
    {
        if (path == null) {
            String temp = JadeSystem.getProperty(TEMP_HOME);
            if (StringUtils.isBlank(temp)) {
                path = new File(JadeSystem.getHome(), "temp");
            }
            else {
                path = new File(temp);
            }
        }
        super.init();

        executorService = Executors.newSingleThreadScheduledExecutor();
        int period = keepTime / 2;
        if (period > 5 * 60 * 1000) {
            period = 5 * 60 * 1000;
        }
        executorService.scheduleWithFixedDelay(this, 60000, period, TimeUnit.MILLISECONDS);
    }

    @PreDestroy
    public void stop()
    {
        if (executorService != null) {
            executorService.shutdown();
        }
    }

    public void run()
    {
        long time = System.currentTimeMillis() - keepTime;
        clear(path, time, false);
        for (int i = 0; i < dirCount; i++) {
            File file = pool[i];
            clear(file, time, true);
        }
    }

    private static class IsFileFilter implements FileFilter
    {
        /**
         * Tests whether or not the specified abstract pathname should be
         * included in a pathname list.
         *
         * @param file The abstract pathname to be tested
         * @return <code>true</code> if and only if <code>pathname</code>
         *         should be included
         */
        public boolean accept(File file)
        {
            return file.isFile();
        }
    }

    private static void clear(File path, long time, boolean rmDir)
    {
        File[] list = rmDir ? path.listFiles() : path.listFiles(new IsFileFilter());
        if (list != null) {
            for (File aList : list) {
                if (aList.lastModified() < time) {
                    org.apache.commons.io.FileUtils.deleteQuietly(aList);
                }
            }
        }
    }
}
